<template>
  <div
    class="chat-container"
    :class="{ fullscreen: fullscreen, compact: compact }"
  >
    <el-card class="chat-card" :class="{ 'no-shadow': noShadow }">
      <!-- 固定在顶部的上传区域 -->
      <template #header>
        <div class="chat-header">
          <h2>AI 文档分析助手</h2>
          <el-upload
            class="upload-btn"
            action=""
            :show-file-list="false"
            :before-upload="beforeUpload"
            :http-request="uploadFile"
            :disabled="isProcessing"
          >
            <el-button type="primary" :icon="Upload" :loading="isUploading">
              {{ isUploading ? "上传中..." : "上传文档" }}
            </el-button>
          </el-upload>
        </div>
      </template>

      <!-- 可滚动的消息区域 -->
      <div class="chat-messages" ref="messagesContainer">
        <!-- <transition-group name="message-fade"> -->
        <div
          v-for="(message, index) in messages"
          :key="index"
          class="message"
          :class="message.role"
        >
          <div class="message-avatar">
            <el-avatar :icon="message.role === 'user' ? User : Comment" />
          </div>
          <div class="message-content">
            <div class="message-meta">
              <span class="message-role">{{
                message.role === "user" ? "你" : "AI助手"
              }}</span>
              <span class="message-time">{{ formatTime(message.time) }}</span>
            </div>
            <div class="message-text">
              <template v-if="message.loading && !message.content">
                <div class="loading-animation">
                  <div class="dot-flashing"></div>
                </div>
              </template>
              <template v-else>
                <div
                  v-if="message.type === 'text'"
                  class="text-content"
                  v-html="formatContent(message.content || '')"
                ></div>
                <div v-else-if="message.type === 'file'" class="file-message">
                  <!-- 添加红色感叹号（上传失败时显示） -->
                  <el-icon
                    v-if="message.error"
                    color="#F56C6C"
                    class="error-icon"
                  >
                    <Warning />
                  </el-icon>
                  <el-icon>
                    <Document />
                  </el-icon>
                  <span class="file-name">{{ message.fileName }}</span>
                  <el-button
                    v-if="message.analysis"
                    size="small"
                    @click="analyzeFile(message.objectName || '')"
                    :disabled="isProcessing"
                  >
                    {{ isAnalyzing ? "分析中..." : "分析文档" }}
                  </el-button>
                </div>
              </template>
            </div>
          </div>
        </div>
        <!-- </transition-group> -->
        <!-- 固定在底部的输入区域 -->
        <div class="chat-input">
          <div class="input-container">
            <el-input
              v-model="inputMessage"
              type="textarea"
              :rows="3"
              placeholder="输入您的问题..."
              @keyup.enter="sendMessage"
              :disabled="isProcessing"
              resize="none"
              class="input-textarea"
            />
            <el-button
              type="primary"
              class="send-btn"
              @click="sendMessage"
              :disabled="!inputMessage.trim() || isProcessing"
              :loading="isResponding"
            >
              发送
            </el-button>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, nextTick, computed } from "vue";

// Props for component configuration
interface Props {
  fullscreen?: boolean;
  compact?: boolean;
  noShadow?: boolean;
  height?: string;
}

const props = withDefaults(defineProps<Props>(), {
  fullscreen: false,
  compact: false,
  noShadow: false,
  height: "auto",
});
import {
  Upload,
  User,
  Comment,
  Document,
  Warning,
} from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import type { UploadRequestOptions } from "element-plus";
import {
  sendChatStream,
  uploadFileToServer,
  analyzeDocumentStream,
  type ChatMessage,
} from "@/api/minio";

// 响应式数据
const messages = ref<ChatMessage[]>([]);
const inputMessage = ref("");
const messagesContainer = ref<HTMLDivElement>();
const isUploading = ref(false);
const isResponding = ref(false);
const isAnalyzing = ref(false);

const isProcessing = computed(
  () => isUploading.value || isResponding.value || isAnalyzing.value
);

// 初始化欢迎消息
onMounted(() => {
  addMessage({
    role: "assistant",
    content: "您好！我是AI文档分析助手，您可以上传文档或直接提问。",
    type: "text",
    time: new Date(),
  });
});

// 添加消息到列表并滚动到底部
const addMessage = async (message: ChatMessage) => {
  messages.value.push(message);
  await nextTick(); // 确保DOM已更新
  scrollToBottom(); // 再滚动
};

// 滚动到消息列表底部
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
};

// 格式化时间显示
const formatTime = (time: Date) => {
  return time.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
};

// 格式化消息内容
const formatContent = (content: string) => {
  return content
    .replace(/\n/g, "<br>")
    .replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" target="_blank">$1</a>');
};

// 发送消息处理
const sendMessage = async () => {
  if (!inputMessage.value.trim() || isProcessing.value) return;

  const userMessage: ChatMessage = {
    role: "user",
    content: inputMessage.value,
    type: "text",
    time: new Date(),
  };
  addMessage(userMessage);
  // 清空输入框
  const aiMessage: ChatMessage = {
    role: "assistant",
    content: "",
    type: "text",
    loading: true,
    time: new Date(),
  };
  // 添加AI消息占位符
  const aiMessageIndex = messages.value.length;
  messages.value.push(aiMessage);
  scrollToBottom();
  inputMessage.value = "";
  isResponding.value = true;
  // 发送请求
  // 使用封装的API发送消息流
  try {
    const eventSource = sendChatStream(userMessage.content);

    // 处理SSE消息
    eventSource.onmessage = (event: MessageEvent) => {
      if (event.data) {
        messages.value[aiMessageIndex].content =
          (messages.value[aiMessageIndex].content || "") + event.data;
        scrollToBottom();
      }
    };
    // 处理SSE错误
    eventSource.onerror = (error: Event) => {
      console.error("SSE错误:", error);
      if (!messages.value[aiMessageIndex].content) {
        messages.value[aiMessageIndex].content = "处理请求时出错";
      }
      messages.value[aiMessageIndex].loading = false;
      isResponding.value = false;
      eventSource.close();
    };
    // 处理完成事件
    eventSource.addEventListener("done", () => {
      messages.value[aiMessageIndex].loading = false;
      isResponding.value = false;
      eventSource.close();
      scrollToBottom();
    });
  } catch (error) {
    console.error("聊天错误:", error);
    messages.value[aiMessageIndex].content = "抱歉，处理您的请求时出错。";
    messages.value[aiMessageIndex].loading = false;
    isResponding.value = false;
    scrollToBottom();
  }
};

// 文件上传前的校验
const beforeUpload = (file: File) => {
  const MAX_SIZE = 2 * 1024 * 1024; // 2MB 与后端保持一致
  if (file.size > MAX_SIZE) {
    ElMessage.error(`文件大小不能超过${MAX_SIZE / 1024 / 1024}MB!`);
    return false;
  }
  return true;
};

// 文件上传处理
const uploadFile = async (options: UploadRequestOptions) => {
  const { file } = options;
  const fileMessage: ChatMessage = {
    role: "user",
    fileName: file.name,
    type: "file",
    loading: true,
    time: new Date(),
    error: false,
  };
  await addMessage(fileMessage); // 使用await确保消息已渲染
  isUploading.value = true;
  // 开始上传文件
  try {
    const response = await uploadFileToServer(file);
    console.log("上传响应:", response);

    fileMessage.objectName = response.data.data.fileName;
    fileMessage.analysis = true;
    fileMessage.loading = false;
    ElMessage.success("文件上传成功!");
  } catch (error) {
    console.error("上传错误:", error);
    fileMessage.content = "文件上传失败";
    fileMessage.loading = false;
    fileMessage.error = true; // 标记为上传失败
    ElMessage.error("文件上传失败!");
  } finally {
    isUploading.value = false;
  }
};

// 分析文件处理
const analyzeFile = async (objectName: string) => {
  if (!inputMessage.value.trim()) {
    ElMessage.warning("请输入您对文档的需求或问题");
    return;
  }
  // 添加用户消息
  const userMessage: ChatMessage = {
    role: "user",
    content: inputMessage.value,
    type: "text",
    time: new Date(),
  };
  addMessage(userMessage);
  // 添加AI消息占位符
  const aiMessage: ChatMessage = {
    role: "assistant",
    content: "",
    type: "text",
    loading: true,
    time: new Date(),
  };
  // 在消息列表中添加AI消息占位符
  const aiMessageIndex = messages.value.length;
  messages.value.push(aiMessage);
  scrollToBottom();
  const userRequest = inputMessage.value;
  inputMessage.value = "";
  isAnalyzing.value = true;
  // 使用封装的API进行文档分析流
  try {
    const eventSource = analyzeDocumentStream(objectName, userRequest);

    eventSource.onmessage = (event: MessageEvent) => {
      if (event.data) {
        messages.value[aiMessageIndex].content =
          (messages.value[aiMessageIndex].content || "") + event.data;
        scrollToBottom();
      }
    };
    // 处理SSE错误
    eventSource.onerror = (error: Event) => {
      console.error("SSE错误:", error);
      if (!messages.value[aiMessageIndex].content) {
        messages.value[aiMessageIndex].content = "处理文档时出错";
      }
      messages.value[aiMessageIndex].loading = false;
      isAnalyzing.value = false;
      eventSource.close();
    };
    // 处理完成事件
    eventSource.addEventListener("done", () => {
      messages.value[aiMessageIndex].loading = false;
      isAnalyzing.value = false;
      eventSource.close();
      scrollToBottom();
    });
  } catch (error) {
    console.error("分析文档错误:", error);
    messages.value[aiMessageIndex].content = "抱歉，分析文档时出错。";
    messages.value[aiMessageIndex].loading = false;
    isAnalyzing.value = false;
    scrollToBottom();
  }
};
</script>

<style scoped>
/* 主容器 - 适配不同使用场景 */
.chat-container {
  width: 100%;
  height: 100%;
  margin: 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  position: relative;
  min-height: 400px; /* 最小高度保证可用性 */
}

/* 全屏模式 */
.chat-container.fullscreen {
  height: 100vh;
  min-height: 100vh;
}

/* 紧凑模式 */
.chat-container.compact {
  min-height: 300px;
}

.chat-container.compact .chat-header {
  padding: 12px 16px;
  min-height: 48px;
}

.chat-container.compact .chat-messages {
  padding: 12px;
  max-height: calc(100% - 140px); /* 头部48px + 输入区域约92px */
}

.chat-container.compact .chat-input {
  padding: 12px 16px;
}

/* 卡片布局 - 更灵活的布局 */
.chat-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

/* 无阴影模式 */
.chat-card.no-shadow {
  box-shadow: none;
  border-radius: 0;
  border: 1px solid var(--el-border-color);
}

/* 顶部头部区域 */
.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  background: var(--el-bg-color);
  border-bottom: 1px solid var(--el-border-color);
  flex-shrink: 0;
  min-height: 60px;
}

/* 消息区域 - 可滚动 */
.chat-messages {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow-y: scroll !important; /* 强制显示滚动条 */
  overflow-x: hidden;
  padding: 16px;
  scroll-behavior: smooth;
  min-height: 200px;
  max-height: calc(100vh - 200px); /* 确保有最大高度限制 */
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.1);
}

/* 底部输入区域 */
.chat-input {
  padding: 16px;
  background: var(--el-bg-color);
  border-top: 1px solid var(--el-border-color);
  flex-shrink: 0;
}

.input-container {
  position: relative;
  width: 100%;
}

.input-textarea {
  padding-right: 80px;
  /* 为按钮留出空间 */
}

.send-btn {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 70px;
  height: 36px;
}

/* 消息项样式 */
.message {
  display: flex;
  max-width: 80%;
  gap: 12px;
  margin-bottom: 16px;
}

.message.user {
  margin-left: auto;
  flex-direction: row-reverse;
}

.message.assistant {
  margin-right: auto;
}

.message-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: calc(100% - 52px);
}

.message-text {
  padding: 12px 16px;
  border-radius: 12px;
  word-break: break-word;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  line-height: 1.5;
  white-space: pre-wrap;
}

.message.user .message-text {
  background-color: var(--el-color-primary-light-9);
  border-top-right-radius: 0;
}

.message.assistant .message-text {
  background-color: var(--el-fill-color-light);
  border-top-left-radius: 0;
}

/* 文件消息样式 */
.file-message {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background-color: var(--el-fill-color-lighter);
  border-radius: 8px;
}

.file-name {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 滚动条样式 */
.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-thumb {
  border-radius: 3px;
  background-color: rgba(0, 0, 0, 0.3);
  transition: background-color 0.2s;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background-color: rgba(0, 0, 0, 0.5);
}

.chat-messages::-webkit-scrollbar-track {
  background-color: rgba(0, 0, 0, 0.1);
  border-radius: 3px;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .chat-container {
    min-height: 300px;
  }

  .chat-input {
    padding: 12px;
  }

  .input-textarea {
    padding-right: 70px;
  }

  .send-btn {
    right: 4px;
    bottom: 4px;
    width: 60px;
    height: 32px;
  }

  .chat-messages {
    min-height: 150px;
    padding: 12px;
  }
}

/* 容器高度自定义 */
.chat-container[style*="height"] {
  min-height: unset;
}

/* 适配父容器 */
.chat-container.fit-parent {
  height: 100%;
  min-height: unset;
  display: flex;
  flex-direction: column;
}

.chat-container.fit-parent .chat-card {
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.chat-container.fit-parent .chat-messages {
  flex: 1;
  overflow-y: scroll !important;
  overflow-x: hidden;
  max-height: none;
  min-height: 0; /* 配合flex:1使用，确保正确的flex收缩 */
}

.chat-container.fit-parent .chat-header {
  flex-shrink: 0; /* 确保头部区域不被压缩 */
}

.chat-container.fit-parent .chat-input {
  flex-shrink: 0; /* 确保输入区域不被压缩 */
}

/* 隐藏头部 */
.chat-container.hide-header .chat-header {
  display: none;
}

/* 简洁模式 - 最小化样式 */
.chat-container.minimal {
  min-height: 250px;
}

.chat-container.minimal .chat-card {
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.chat-container.minimal .chat-header {
  padding: 8px 12px;
  min-height: 40px;
}

.chat-container.minimal .chat-header h2 {
  font-size: 16px;
  margin: 0;
}

.chat-container.minimal .chat-messages {
  padding: 8px 12px;
  min-height: 120px;
}

.chat-container.minimal .chat-input {
  padding: 8px 12px;
}

/* 打字机效果 */
.message.assistant .message-text.loading::after {
  content: "|";
  animation: blink 1s step-end infinite;
  margin-left: 2px;
}

@keyframes blink {
  from,
  to {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }
}

/* 加载动画 */
.loading-animation {
  padding: 12px 16px;
}

.dot-flashing {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background-color: var(--el-color-primary);
  animation: dot-pulse 1.5s infinite ease-in-out;
  animation-delay: 0.2s;
}

.dot-flashing::before,
.dot-flashing::after {
  content: "";
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background-color: var(--el-color-primary);
}

.dot-flashing::before {
  left: -12px;
  animation: dot-pulse 1.5s infinite ease-in-out;
  animation-delay: 0s;
}

.dot-flashing::after {
  left: 12px;
  animation: dot-pulse 1.5s infinite ease-in-out;
  animation-delay: 0.4s;
}

@keyframes dot-pulse {
  0%,
  60%,
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }

  30% {
    transform: scale(1.1);
    opacity: 1;
  }
}

/* 消息过渡效果 */
.message-fade-enter-active,
.message-fade-leave-active {
  transition: all 0.3s ease;
}

.message-fade-enter-from,
.message-fade-leave-to {
  opacity: 0;
  transform: translateY(10px);
}
</style>
